TITL DAI FIRMWARE D790-D8FA V1.1 ORG :D790 * * * ************************ * CHECK FREE RAM SPACE * ************************ * * Entry: DE: Startaddress. * HL: 1st not useable address. * Exit: HL: Useable RAM space. * ABCDE preserved. * MPT25 CALL :DE1A Calculate free space DCX H RET * ********************************** * TRANSFER DATA/CASSETTE VECTORS * ********************************** * * Transfer data/cassette switching vectors from * ROM to RAM vector area. * * Exit: AFBC preserved. DEHL corrupted. * *MPT01 CASIN PUSH B LXI H,:D7CB Highest source address LXI D,:D7A4 Lowest source address LXI B,:02C5 Lowest destination address CALL :DE4F Transfer cassette vectors POP B RET * *********************************** * DATA/CASSETTE SWITCHING VECTORS * *********************************** * * This data block is moved into the RAM area * #02C5-#02EB during system initialisation. * CINTB JMP :D2B8 WOPEN JMP :D2F1 WBLK JMP :D427 WCLOSE JMP :D325 ROPEN JMP :D340 RBLK JMP :D445 RCLOSE JMP :D3A2 MBLK RET RESET NOP NOP RET DOUTC NOP NOP JMP :DDB4 DINC RET NOP NOP DATA :24,:24 TAPSL DATA :24,:3C TAPSD DATA :24,:18 TAPST * ************************************ * WAIT FOR SPACEBAR, PRINT CAR.RET * ************************************ * * Exit: BCDEHL preserved. * CY=1: Break pressed. * *CINTE WPT CALL :D6DA Wait for spacebar JC :C80C If BREAK pressed: into REM Basic monitor JMP :DD5E Print car.ret; ret * DATA :FF DATA :FF DATA :FF DATA :FF * ********************************* * WRITE BLOCK + TRAILER ON TAPE * ********************************* * * Entry: DE: Length block. * HL: Startaddress block. * Exit: A=0, BCDE preserved. * HL points past block written. * MPT10 CALL :02C8 Write block JMP :02CB Write trailer * ************************ * FAILURE DURING ROPEN * ************************ * RPN20 DCR C INR C Load during program ? CNZ :DD5E Print car.ret if not JMP :D329 Back to read file leader * ***************************** * PRINT MESSAGE ON NEW LINE * ***************************** * * New routine. It moves the cursor to a new line * before a message is printed. Used for printing * 'STOPPED IN LINE ...' and 'END PROGRAM'. * CALL :DD55 ] Cursor to column 0 JMP :DAFF ] Print message * ***************** * FAST PRINTING * ***************** * * Instruction only moved. * PUSH H LHLD :0072 Get cursor position address MOV M,A Write byte on screen DCX H ) Update cursor addr DCX H ) SHLD :0072 Save new cursor address POP H RET * *************************** * SAVE: WRITE NAME LENGTH * *************************** * * Entry: HL: Addr. length byte of name. * Exit: DE: Length of name. * HL: Points past string. * BC: Preserved. * A: Checksum on string. * MPT22 MOV E,M Get name length MVI D,:00 INX H HL to 1st byte of name JMP :D2F1 Write name length * ******************************** * INITIALISE LOADING FROM TAPE * ******************************** * * Entry: HL: Points to length byte of name requested * Exit: DE: Length requested name. * HL: Points to first byte of name. * AFBC preserved. * MPT23 MOV E,M Get length requested name MVI D,:00 in DE INX H HL points to 1st byte name JMP :D42E Cassette motors on; ret * ********************* * UPDATE POROM/PORO * ********************* * * Entry: MPT52: Byte for ROM/cassette select in A. * MPT53: New POROM byte. * MPT52 ANI :F0 Enable ROM/cassette select MPT53 STA :0040 Load POROM STA :FD06 and PORO RET * ***************** * part of 2EAC1 * ***************** * * If pointer is off top visible screen: * PCK40 MOV A,D CPI :D0 JC :EAEF (2) if <= CF (no overflow REM below 0) PUSH H ) if > CF: PUSH B ) Exchange BC and HL POP H ) POP B ) JMP :EAEF (2) * DATA :FF * ********************** * RUN basiccmd SAVEA * ********************** * RSAVA CALL :D83B Evaluate array type to be REM saved PUSH PSW Save type array JNZ :D826 Jump if INT/FPT array RST 4 Move stringarray into one DATA :75 string in free RAM LD99 POP PSW Get type array PUSH H PUSH D PUSH PSW CALL :E791 (0) Evaluate program name MVI A,:32 File type byte '2' CALL :02C5 WOPEN POP PSW Get type array LXI H,:013E Startaddr EBUF MOV M,A Type into EBUF JMP :D668 Write 2 blocks + trailer * NOP * ****************************************** * EVALUATE ARRAY TYPE TO BE SAVED/LOADED * ****************************************** * * Exit: A: Array type. * DE: Length all array elements. * HL: Beginaddr. 1st array element. * Z=1: String array. * Z=0: INT/FPT array. * RLSAS CALL :E95A (0) Get array addr in HL ANI :30 Allow any type array PUSH PSW Save type MOV E,M ) INX H ) Get array pntr in DE MOV D,M ) MOV A,E ORA D JZ :E990 (0) Undef. array if no addr XCHG Pointer to array in HL DCX H DCX H MOV D,M Get 1st length byte INX H MOV A,M Get 2nd length byte INX H SUB M Minus nr of dim. bytes MOV E,A MOV A,D SBI :00 Update hibyte if borrow MOV D,A DCX D DE is length all array elem. CALL :DE39 HL is beginaddr 1st element POP PSW Get type in A CPI :20 Set Z-flag on type RET * ********************** * RUN basiccmd LOADA * ********************** * RLODA CALL :D83B Evaluate array type to be REM loaded PUSH H Save startaddr array elem. PUSH PSW Save type CALL :D678 Evaluate requested program REM name; prep. select ROM bank CALL :D808 Select ROM bank 1 POP PSW Get type JMP :EE0F (1) Read block from tape and REM store it in array * ************************************ * INITIALISE 'EDIT': EMPTY HEAP, * * CLEAR SYMBOL TABLE, MOVE PROGRAM * ************************************ * * Part of 'Init. EDIT' (0E265). * * Entry: CY=1: Not sufficient memory available. * MPT33 JC :DA10 Evt. run error 'OUT OF REM MEMORY' JMP :CB23 Empty heap, move REM program, clear symtab * ****************************************** * LIST CURRENT LINE IF LINENR IS CORRECT * ****************************************** * * Part of 'run LIST ' (0E1B6). * * Entry: CY=0 if linenr. <= 0 or > FFFF. * MPT3A JNC :DA15 Evt. run error 'NUMBER REM OUT OF RANGE' JMP :ECAB (0) List current line * ************************** * INPUT FROM EDIT BUFFER * ************************** * * Part of 'restart interpreter' (C823). * MPT05 PUSH H CALL :E291 (0) Input from editbuffer POP H RET * ******************************* * part of RUN 'CLEAR' (0E6B5) * ******************************* * * Checks for heap too big. * MPT42 POP H ] Get difference DAD B ] Add textpntr MOV B,H ] New textpntr in BC MOV C,L ] ORA A ] No special action RET ] DATA :FF ] * ************************************ * EVT. INITIALISE 4 COLOUR ANIMATE * ************************************ * * Part of 2E9C3. * SPT04 CPI :14 RNC Abort if A >= 14 STA :00C1 Set for 4-colour animate RET * ******** * DATA * ******** * LD221 DATA :20 Space DATA :8C,:72 Pntr. to 'MODE' DATA :00 * ****************************** * part of 1EE0B - (not used) * ****************************** * LD105 PUSH PSW CALL :E791 (1) POP PSW RET * ******************************************* * READ BLOCK FROM TAPE, EVT. ERROR REPORT * ******************************************* * * Part of LOADA (1EE0F). * MPT19 CALL :02D1 Read block from tape * ************************ * READ BLOCK FROM TAPE * ************************ * * Now cassette motors are switched off directly * after reading is finished. * Especially in LOADA, switching off the cassette * motors after re-arranging all data was very * annoying. * JMP :D265 Evt. run 'LOADING ERROR' RET * ************************************** * LIST ARRAY NAME, SPACE, EXPRESSION * ************************************** * * Used in listing 'Savea/Loada' textlines. * SCN30 CALL :EEF7 (0) List array name JMP :ED65 (0) List space, expression * DATA :FF DATA :FF * ****************************** * INITIALISE SOUND GENERATOR * ****************************** * * All sound channels are switched off. * * Exit: AB preserved, CDEHLF corrupted. * SNDINI LXI H,:FC06 MVI M,:36 ) Load 3 timers MVI M,:76 ) MVI M,:B6 ) LXI H,:0000 SHLD :FD04 Volume 4 channels off SHLD :0294 and remember it LXI H,:01C2 Start 1st SCB LXI D,:000E Length SCB MVI C,:04 4 blocks (3 SCB, 1 NCB) SNI10 MVI M,:FF FF in 1st byte SCB (= off) DAD D Calc start next block DCR C JNZ :D8C0 Next block if not ready RET * ********************* * OUTPUT TO DCE-BUS * ********************* * * 'Real World' output. Writes a byte to a given * Real World address. * * Entry: D: Busaddress. * E: Data for output. * RWOP PUSH PSW PUSH H LXI H,:FE03 GIC control address MVI M,:80 All ports output DCX H Port C addr. in HL MVI M,:FE Clear bus expand signal XCHG Data in L, busaddr. in H SHLD :FE00 Data in PA, busaddr. in PB XCHG Address PC in HL INR M Set bus expand signal MVI M,:FD Set write strobe true REM (Now data exchange done) MVI M,:FF Reset strobe DCR M Clear bus expand signal POP H POP PSW RET * ********************** * INPUT FROM DCE-BUS * ********************** * * 'Real World' input. Reads a byte from a given * Real World address. * * Entry: D: Busaddress. * Exit: E: Data received. * RWIP PUSH PSW PUSH H LXI H,:FE03 GIC control addr. in HL MVI M,:90 PA input, rest output DCX H Address PC in HL MVI M,:FE Clear bus expand signal MOV A,D Busaddress in A STA :FE01 Store busaddress in PB INR M Set bus expand signal MVI M,:FB Set read strobe true REM (Now data exchange) LDA :FE00 Data to A MOV E,A Data in E MVI M,:FF Reset strobe DCR M POP H POP PSW RET * * * UNL CINTE EQU WPT MPT01 EQU CASIN LST END